home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / macabuse / src / scene.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-20  |  15.1 KB  |  704 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #include "specs.hpp"
  5. #include "timage.hpp"
  6. #include "jwindow.hpp"
  7. #include "fonts.hpp"
  8. #include "timing.hpp"
  9. #include "scene.hpp"
  10. #include "game.hpp"
  11. #include "parse.hpp"
  12. #include "cache.hpp"
  13. #include <fcntl.h>
  14.  
  15.  
  16. class string_node
  17. {
  18.   string_node *l,*r;
  19.   char *n;
  20. public :  
  21.   string_node(char *Name, string_node *Left=NULL, string_node *Right=NULL)
  22.   { l=Left;
  23.     r=Right;
  24.     n=strcpy((char *)jmalloc(strlen(Name)+1,"string node"),Name);
  25.   }
  26.   ~string_node() { jfree(n); }               
  27.   char *name() { return n; }
  28.   string_node *left() { return l; }
  29.   string_node *right() { return r; }                       
  30. } ;
  31.  
  32.  
  33. /*class string_tree
  34. {
  35.   string_node *root;
  36. public :
  37.   string_tree() { root=NULL; }
  38.   void insert(char *name);
  39.      
  40. } ; */
  41.  
  42.  
  43.  
  44. char scene_filename[100];
  45.  
  46. class scene_frame
  47. {
  48. public :
  49.   int picture;
  50.   long time,xc,yc;  
  51.  
  52.   scene_frame *next;  
  53.   scene_frame(char *&s);
  54.   ~scene_frame() { cash.unreg(picture); }
  55. } ;
  56.  
  57.  
  58. scene_frame::scene_frame(char *&s)
  59. {
  60.   char tmp_name[50];
  61.   expect(get_token(s,tmp_name),sWORD,s);
  62.  
  63.   picture=cash.reg(scene_filename,tmp_name);
  64.   if (picture<0) 
  65.   {
  66.     printf("Frame image not found (%s)\n",tmp_name);
  67.     exit(0);
  68.   }
  69.  
  70.   
  71.   xc=yc=0;
  72.   time=-1;  
  73.   if (token_type(s)==sLEFT_PAREN)  // is a descriptor included?
  74.   {
  75.     next_token(s);
  76.     
  77.     xc=get_number(s);
  78.     if (token_type(s)!=sRIGHT_PAREN)
  79.     {      
  80.       yc=get_number(s);
  81.       if (token_type(s)!=sRIGHT_PAREN)
  82.         time=get_number(s);
  83.     }    
  84.     expect(get_token(s,tmp_name),sRIGHT_PAREN,s);    
  85.   }
  86.  
  87.   next=NULL;  
  88. }
  89.  
  90.  
  91.  
  92. class scene_sequence : public linked_node
  93. {
  94. public :   
  95.   char *n;
  96.   scene_frame *first;
  97.   scene_sequence *next;  
  98.   scene_sequence(char *&s);
  99.   ~scene_sequence();
  100. } ;
  101.  
  102.  
  103.  
  104. scene_sequence::~scene_sequence()
  105. { jfree(n); 
  106.   while (first) 
  107.   { scene_frame *p=first; 
  108.     first=first->next;
  109.     delete p; 
  110.   }
  111. }
  112.  
  113.  
  114. scene_sequence::scene_sequence(char *&s)
  115. {
  116.   scene_frame *cur;
  117.   char tmp_name[50];
  118.   expect(token_type(s),sLEFT_PAREN,s);    
  119.   next_token(s);
  120.  
  121.   expect(get_token(s,tmp_name),sWORD,s);  
  122.   n=strcpy((char *)jmalloc(strlen(tmp_name)+1,"sequence name"),tmp_name);  
  123.   cur=first=new scene_frame(s);  
  124.  
  125.   while (token_type(s)!=sRIGHT_PAREN)    
  126.   {
  127.     cur->next=new scene_frame(s);
  128.     cur=cur->next;    
  129.  
  130.     next=NULL;  
  131.   }  
  132.   next_token(s);  
  133.   next=NULL;  
  134. }
  135.  
  136.  
  137. class scene_sequence_list
  138. {
  139. public :
  140.   scene_sequence *first;
  141.   scene_sequence_list(char *&s);  
  142.   scene_sequence *get_seq(char *seq_name);
  143.   ~scene_sequence_list();  
  144. } ;
  145.  
  146. scene_sequence_list::~scene_sequence_list()
  147. {
  148.   scene_sequence *p;
  149.   while (first)
  150.   {
  151.     p=first;
  152.     first=first->next;
  153.     delete p;    
  154.   }
  155. }  
  156.  
  157. scene_sequence_list::scene_sequence_list(char *&s)
  158.   scene_sequence *cur;  
  159.   expect(token_type(s),sLEFT_PAREN,s);    
  160.   next_token(s);
  161.  
  162.   cur=first=new scene_sequence(s);   
  163.   while (token_type(s)!=sRIGHT_PAREN)
  164.   {
  165.     cur->next=new scene_sequence(s);
  166.     cur=cur->next;    
  167.   }    
  168.   next_token(s);  
  169. }
  170.  
  171. scene_sequence *scene_sequence_list::get_seq(char *seq_name)
  172. {
  173.   scene_sequence *s=first;
  174.   while (s && strcmp(s->n,seq_name)) s=s->next;
  175.   if (!s) 
  176.   {
  177.     printf("No sequence named %s\n",seq_name);
  178.     exit(1);    
  179.   }
  180.   return s;       
  181. }
  182.  
  183.  
  184. class scene_character
  185. {
  186.   scene_sequence_list *seq_list;
  187.  
  188.   game_object *me;
  189.   
  190. public :
  191.   char *n;  
  192.   scene_character *next;
  193.   scene_sequence *current_seq;    
  194.   scene_frame *current_frame;
  195.   
  196.   time_marker *last_frame;
  197.   void draw();  
  198.   void area(int &x1, int &y1, int &x2, int &y2);  
  199.   scene_character(char *&s);  
  200.   void set_seq(char *seq_name) 
  201.   { current_seq=seq_list->get_seq(seq_name); }
  202.   int x() { return the_game->screenx(me->x)-cash.fig(current_frame->picture)->xcfg; }          
  203.   int y() { return the_game->screeny(me->y)-cash.fig(current_frame->picture)->forward->height(); }
  204.   int next_frame();  // true if sequence is done
  205.   ~scene_character() { jfree(n); delete seq_list; if (last_frame) delete last_frame; }     
  206. } ;
  207.  
  208.  
  209. int scene_character::next_frame()
  210. {
  211.   me->x+=current_frame->xc;
  212.   me->y+=current_frame->yc;
  213.  
  214.   current_frame=current_frame->next;        // advance the picture
  215.  
  216.   if (last_frame)                           // save the time stamp, delete old one
  217.     delete last_frame;        
  218.   last_frame=new time_marker;        
  219.  
  220.   if (!current_frame)                      // end of sequence?
  221.   {          
  222.     current_frame=current_seq->first;       // reset and return 1
  223.     return 1;
  224.   } 
  225.   else return 0;
  226. }
  227.  
  228.  
  229. void scene_character::area(int &x1, int &y1, int &x2, int &y2)
  230. {
  231.    
  232.   x1=x();
  233.   y1=y();
  234.   y2=x2=0;
  235.   
  236.   scene_frame *p=current_seq->first;
  237.   while (p)
  238.   {    
  239.     if (x()+cash.fig(p->picture)->width()-1>x2)
  240.       x2=x()+cash.fig(p->picture)->width()-1;
  241.     if (y()+cash.fig(p->picture)->height()-1>y2)
  242.       y2=y()+cash.fig(p->picture)->height()-1;
  243.     p=p->next;
  244.   }  
  245. }
  246.  
  247.  
  248. void scene_character::draw()
  249. {
  250.   cash.fig(current_frame->picture)->forward->put_image(screen,x(),y());
  251.   
  252. }
  253.  
  254.  
  255. scene_character::scene_character(char *&s)
  256. {
  257.   char tmp[100];  
  258.   expect(get_token(s,tmp),sLEFT_PAREN,s);        
  259.   expect(get_token(s,tmp),sWORD,s);              
  260.   n=strcpy((char *)jmalloc(strlen(tmp)+1,"scene character name"),tmp);  
  261.   expect(get_token(s,tmp),sNUMBER,s);    
  262.  
  263. /*  if (atoi(tmp)==0) */
  264.  
  265.   me=current_level->main_character();
  266.  
  267.   
  268.   seq_list=new scene_sequence_list(s);          
  269.   current_seq=seq_list->first;  
  270.   current_frame=current_seq->first;
  271.   expect(get_token(s,tmp),sRIGHT_PAREN,s);          
  272.  
  273.   last_frame=NULL;
  274.   next=NULL;  
  275. }
  276.  
  277.  
  278. class scene_character_list
  279. {
  280. public :
  281.   scene_character *first;
  282.   scene_character_list(char *&s);  
  283.   void inital_states(char *&s);  
  284.   scene_character *get(char *name);   
  285.  ~scene_character_list();  
  286. } ;
  287.  
  288. scene_character  *scene_character_list::get(char *name)
  289. {
  290.   scene_character *s=first;
  291.   while (s)
  292.   {
  293.     if (!strcmp(s->n,name)) return s;
  294.     s=s->next;
  295.   }
  296.   printf("Character %s not found!\n",name);
  297.   exit(1);  
  298. }
  299.  
  300.  
  301. scene_character_list::~scene_character_list()
  302. {
  303.   scene_character *p;
  304.   while (first)
  305.   {
  306.     p=first;
  307.     first=first->next;
  308.     delete p;    
  309.   }
  310. }  
  311.  
  312. scene_character_list::scene_character_list(char *&s)
  313.   scene_character *cur;  
  314.   expect(token_type(s),sLEFT_PAREN,s);    
  315.   next_token(s);
  316.  
  317.   cur=first=new scene_character(s);
  318.     
  319.   while (token_type(s)!=sRIGHT_PAREN)
  320.   {
  321.     cur->next=new scene_character(s);
  322.     cur=cur->next;    
  323.   }    
  324.   next_token(s);  
  325. }
  326.  
  327.  
  328. void scene_character_list::inital_states(char *&s)
  329. {
  330.   char ch[50],seq[50];
  331.  
  332.   do
  333.   {
  334.     expect(get_token(s,ch),sLEFT_PAREN,s);  
  335.     expect(get_token(s,ch),sWORD,s);      
  336.     expect(get_token(s,seq),sWORD,s);      
  337.     scene_character *c=first;
  338.     while (c && strcmp(c->n,ch)) c=c->next;
  339.     if (!c)
  340.     {
  341.       printf("No character named %s, at %s\n",ch,s);
  342.       exit(0);
  343.     } else c->set_seq(seq);       
  344.     expect(get_token(s,ch),sRIGHT_PAREN,s);  
  345.   } while (token_type(s)!=sRIGHT_PAREN);
  346. }
  347.  
  348. class text_blocker
  349. {
  350. public :  
  351.   int x1,y1,x2,y2;  
  352.   text_blocker *next;
  353.   text_blocker(int X1, int Y1, int X2, int Y2, text_blocker *Next) 
  354.   { x1=X1;
  355.     y1=Y1;
  356.     x2=X2;
  357.     y2=Y2;
  358.     next=Next;    
  359.   }     
  360. } ;
  361.  
  362.  
  363. int text_draw(int y, int x1, int y1, int x2, int y2, char *buf, 
  364.           text_blocker *first, JCFont *font)
  365. {
  366.   short cx1,cy1,cx2,cy2,word_size,word_len;
  367.   screen->get_clip(cx1,cy1,cx2,cy2);
  368.   screen->in_clip(x1,y1,x2,y2);  
  369.   int h=font->height()+2,w=font->width(),x=x1,dist;
  370.   y+=y1;
  371.   char *word_start;
  372.  
  373.   while (*buf)
  374.   {
  375.     do 
  376.     {  
  377.       if (*buf=='\\' && buf[1]=='n')
  378.       {
  379.     x=x1;
  380.     y+=h*2;
  381.     buf+=2;
  382.       }
  383.       
  384.       // skip space
  385.       if (*buf==' ' || *buf=='\r' || *buf=='\n' || *buf=='\t')
  386.       {          
  387.     x+=w;
  388.     while (*buf==' ' || *buf=='\r' || *buf=='\n' || *buf=='\t')   // skip space until next word
  389.           buf++;
  390.       }
  391.  
  392.       word_start=buf;
  393.       for (word_len=0,word_start=buf,word_size=0;*buf && *buf!=' ' && *buf!='\r' && *buf!='\n' && 
  394.        *buf!='\t' && (*buf!='\\' || buf[1]!='n');buf++,word_size+=w,word_len++);
  395.       
  396.       if (word_size<x2-x1) // make sure the word can fit on the screen
  397.       {
  398.     if (word_size+x>x2)    // does word not fit on line?
  399.     {
  400.       y+=h;                // go to next line
  401.       x=x1;      
  402.     }
  403.       }
  404.  
  405.  
  406.       if (y+h<y1)         // word on screen yet?
  407.     x+=word_size;
  408.  
  409.     } while (y+h<y1);     // if not on screen yet, fetch next word
  410.  
  411. /*    dist=100;
  412.     for (n=first;n;n=n->next)      
  413.     {
  414.       if (x<n->x1)
  415.         minx=(n->x1-x);
  416.       else if (x>n->x2)
  417.         minx=(x-n->x2);
  418.       else minx=0;
  419.  
  420.       if (y<n->y1)
  421.         miny=(n->y1-y);
  422.       else if (y>n->y2)
  423.         miny=(y-n->y2);
  424.       else miny=0;
  425.       
  426.       dist=min(dist,max(minx,miny));
  427.     }
  428.       
  429.       
  430.     if (dist<=8) dist=8;
  431.     else if (dist>31) dist=31;      */
  432.  
  433.     dist=31;
  434.     if (y-y1<dist)
  435.       if (y-y1<8) dist=8;
  436.       else dist=y-y1;
  437.     if (y2-y<dist)
  438.       if (y2-y<8) dist=8;
  439.       else dist=y2-y;         
  440.  
  441.     if (y>y2) return 0;
  442.  
  443.     while (word_len--)
  444.     {
  445.       font->put_char(screen,x+1,y+1,*word_start,0);
  446.       font->put_char(screen,x,y,*word_start,32-dist);
  447.       word_start++;
  448.       x+=w;      
  449.     }
  450.  
  451.   }
  452.  
  453.   screen->set_clip(cx1,cy1,cx2,cy2);
  454.   return (y<=y1);  
  455. }
  456.  
  457.  
  458. struct scene_data_struct       // define a name for the structure so that we can inspect in gdb
  459. {
  460.   int x1,y1,x2,y2,
  461.       pan_vx,pan_yv,pan_steps,
  462.       frame_speed,scroll_speed,pan_speed;  
  463. } scene_data;
  464.  
  465.  
  466.  
  467.     
  468.  
  469. void play_scene(char *script, char *filename, JCFont *font)
  470. {
  471.   char *s=script;  
  472.   char token[90];
  473.   text_blocker *text_blockers=NULL;
  474.  
  475.   char *strng=(char *)jmalloc(MAX_SCROLL_DATA,"tmp token space");  
  476.   strcpy(scene_filename,filename);
  477.   
  478.   int x1,y1,x2,y2,done,pan_xv=0,pan_yv=0,pan_steps=0,
  479.       text_loaded=0,frame_speed=100,scroll_speed=50,pan_speed=60,abort=0,text_step=-2;
  480.  
  481.   short cx1,cy1,cx2,cy2;  
  482.  
  483.   the_game->draw(1);
  484.  
  485.   screen->get_clip(cx1,cy1,cx2,cy2);
  486.   screen->set_clip(the_game->viewx1,the_game->viewy1,
  487.            the_game->viewx2,the_game->viewy2);
  488.   
  489.   
  490.   
  491.  
  492.   expect(get_token(s,token),sLEFT_PAREN,s);  
  493.   scene_character_list cl(s);
  494.   int y;
  495.  
  496.   do
  497.   {
  498.     expect(get_token(s,token),sLEFT_PAREN,s);   // list of transitions start
  499.     // ACTIONS    
  500.     time_marker *last_text_time=NULL;    
  501.     time_marker *last_pan_time=NULL;
  502.     do
  503.     {      
  504.       expect(get_token(s,token),sLEFT_PAREN,s);         
  505.       expect(get_token(s,token),sWORD,s);
  506.  
  507.       if (!strcmp(token,"pan"))
  508.       {
  509.     pan_xv=get_number(s);
  510.     pan_yv=get_number(s);
  511.         pan_steps=get_number(s);
  512.       }
  513.       else if (!strcmp(token,"states"))
  514.         cl.inital_states(s);
  515.       else if (!strcmp(token,"scroll_speed"))
  516.         scroll_speed=get_number(s);
  517.       else if (!strcmp(token,"pan_speed"))
  518.         pan_speed=get_number(s);
  519.       else if (!strcmp(token,"frame_speed"))
  520.         frame_speed=get_number(s);      
  521.       else if (!strcmp(token,"text_region"))
  522.       {
  523.     x1=the_game->viewx1+get_number(s);
  524.     y1=the_game->viewy1+get_number(s);
  525.     x2=the_game->viewx1+get_number(s);
  526.     y2=the_game->viewy1+get_number(s);    
  527.     y=y2-y1;
  528.       } else if (!strcmp(token,"text_block"))
  529.       {
  530.     int sx1=get_number(s)+the_game->viewx1;
  531.     int sy1=get_number(s)+the_game->viewy1;
  532.     int sx2=get_number(s)+the_game->viewx1;
  533.     int sy2=get_number(s)+the_game->viewy1;
  534.     text_blockers=new text_blocker(sx1,sy1,sx2,sy2,text_blockers);
  535.       } else if (!strcmp(token,"block"))
  536.       {
  537.     int sx1,sy1,sx2,sy2;
  538.     expect(get_token(s,token),sWORD,s);    
  539.     cl.get(token)->area(sx1,sy1,sx2,sy2);
  540.     text_blockers=new text_blocker(sx1,sy1,sx2,sy2,text_blockers);    
  541.       }            
  542.       else if (!strcmp(token,"scroll"))
  543.       {
  544.     expect(get_token(s,strng),sSTRING,s);
  545.     text_loaded=1;
  546.     y=y2-y1;
  547.       } else if (!strcmp(token,"wait"))
  548.       {
  549.     expect(get_token(s,token),sWORD,s);
  550.     printf("waiting for %s\n",token);    
  551.     done=0;
  552.  
  553.  
  554.  
  555.  
  556.     int old_dev=dev;
  557.     dev=dev&(0xffff-DRAW_PEOPLE_LAYER);    
  558.  
  559.  
  560.     do
  561.     {    
  562.       the_game->draw_map();
  563.  
  564.       time_marker cur_time;
  565.       if (pan_steps)
  566.       {
  567.         if (last_pan_time)
  568.         {
  569.           if ((int)(cur_time.diff_time(last_pan_time)*1000)>pan_speed)
  570.           {
  571.         the_game->pan(pan_xv,pan_yv);
  572.         pan_steps--;
  573.         delete last_pan_time;
  574.         if (pan_steps)
  575.            last_pan_time=new time_marker;
  576.         else last_pan_time=NULL;
  577.           }
  578.         } else last_pan_time=new time_marker;
  579.       }
  580.  
  581.       scene_character *first=cl.first;
  582.       while (first)
  583.       {
  584.         first->draw();
  585.         
  586.         if (!first->last_frame)
  587.           first->last_frame=new time_marker;
  588.         else
  589.         {
  590.           int time=first->current_frame->time,advance=0;
  591.           if (time>=0)
  592.           {                
  593.              if ((int)(cur_time.diff_time(first->last_frame)*1000)>time)
  594.           advance=1;
  595.           }
  596.           else
  597.           {
  598.         if ((int)(cur_time.diff_time(first->last_frame)*1000)>frame_speed)
  599.           advance=1;        
  600.           }
  601.         
  602.           if (advance)
  603.           {
  604.             if (!strcmp(token,first->n))      // is this the character we are waiting on?
  605.         {
  606.               if (first->next_frame())
  607.             done=1;
  608.         } else first->next_frame();
  609.           }
  610.         }        
  611.         first=first->next;        
  612.       }
  613.       if (text_loaded)
  614.       {
  615.         text_loaded=(!text_draw(y,x1,y1,x2,y2,strng,text_blockers,font));
  616.         if (last_text_time)
  617.         {
  618.           if ((int)(cur_time.diff_time(last_text_time)*1000)>scroll_speed)
  619.           {          
  620.               y+=text_step;
  621.             delete last_text_time;
  622.         if (text_loaded)
  623.           last_text_time=new time_marker;        
  624.         else
  625.           last_text_time=NULL;
  626.           }
  627.         } else last_text_time=new time_marker;        
  628.       } 
  629.  
  630.       
  631.       
  632.       if (!strcmp(token,"pan"))      
  633.         if (pan_steps<=0) done=1;
  634.  
  635.       if (!strcmp(token,"text"))
  636.         if (!text_loaded) done=1;
  637.         
  638.       eh->flush_screen();      
  639.       while (eh->event_waiting())
  640.       {    
  641.         event ev;        
  642.         eh->get_event(ev);
  643.         if (ev.type==EV_KEY)
  644.         {
  645.           switch (ev.key)
  646.           {
  647.             case JK_UP :
  648.             case JK_LEFT : 
  649.           if (scroll_speed>=20) 
  650.             scroll_speed-=20; 
  651.           else text_step--;
  652.           break;
  653.         case JK_RIGHT :
  654.         case JK_DOWN : 
  655.           if (text_step<-2)
  656.             text_step++;
  657.           else if (scroll_speed<200) scroll_speed+=20; 
  658.           break;
  659.         case JK_ESC : abort=done=1; break;
  660.         case JK_ENTER : done=1; break;
  661.           }
  662.         }
  663.       }
  664.       
  665.       
  666.     } while (!done);
  667.     dev=old_dev;
  668.       }      
  669.             
  670.       expect(get_token(s,token),sRIGHT_PAREN,s);     
  671.       
  672.     } while (!abort && token_type(s)!=sRIGHT_PAREN);
  673.  
  674.     
  675.     if (!abort)
  676.       next_token(s);
  677.  
  678.     // free up memory allocated 
  679.     while (text_blockers)
  680.     {
  681.       text_blocker *n=text_blockers->next;      
  682.       delete text_blockers;
  683.       text_blockers=n;      
  684.     }
  685.     if (last_text_time)
  686.       delete last_text_time;
  687.     if (last_pan_time)
  688.       delete last_pan_time;
  689.  
  690.   } while (!abort && token_type(s)!=sRIGHT_PAREN);  
  691.   if (!abort)
  692.     next_token(s);
  693.  
  694.   jfree(strng);
  695.   screen->set_clip(cx1,cy1,cx2,cy2);  
  696.  
  697.   the_game->draw(0);
  698. }
  699.  
  700.  
  701.  
  702.